package com.fengyi.library.service;

import com.fengyi.library.DTO.BookDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.circuitbreaker.CircuitBreaker;
import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 图书查询熔断器服务
 * 使用熔断器模式调用图书查询服务
 */
@Service
public class BookCircuitBreakerService {

    private static final String CIRCUIT_BREAKER_NAME = "bookQueryCircuitBreaker";
    
    @Autowired
    private BookService bookService;
    
    @Autowired
    private CircuitBreakerFactory circuitBreakerFactory;
    
    /**
     * 使用熔断器根据ID查询图书
     * @param id 图书ID
     * @return 图书信息
     */
    public BookDTO findBookById(Integer id) {
        System.out.println("使用熔断器查询图书 - ID: " + id);
        
        CircuitBreaker circuitBreaker = circuitBreakerFactory.create(CIRCUIT_BREAKER_NAME);
        
        return circuitBreaker.run(
            () -> {
                try {
                    BookDTO result = bookService.findById(id);
                    System.out.println("图书查询成功，返回结果: " + result.getTitle());
                    return result;
                } catch (Exception e) {
                    System.out.println("图书查询失败: " + e.getMessage());
                    throw e;
                }
            },
            throwable -> {
                System.out.println("触发图书查询熔断降级: " + throwable.getMessage());
                return createFallbackBook(id);
            }
        );
    }
    
    /**
     * 使用熔断器查询所有图书
     * @return 图书列表
     */
    public List<BookDTO> findAllBooks() {
        System.out.println("使用熔断器查询所有图书");
        
        CircuitBreaker circuitBreaker = circuitBreakerFactory.create(CIRCUIT_BREAKER_NAME);
        
        return circuitBreaker.run(
            () -> {
                try {
                    List<BookDTO> result = bookService.findAllBooks();
                    System.out.println("图书查询成功，返回结果数量: " + result.size());
                    return result;
                } catch (Exception e) {
                    System.out.println("图书查询失败: " + e.getMessage());
                    throw e;
                }
            },
            throwable -> {
                System.out.println("触发图书查询熔断降级: " + throwable.getMessage());
                return createFallbackBookList();
            }
        );
    }
    
    /**
     * 使用熔断器分页查询图书
     * @param page 页码
     * @param size 每页大小
     * @return 分页图书列表
     */
    public Page<BookDTO> findBooksByPage(int page, int size) {
        System.out.println("使用熔断器分页查询图书");
        System.out.println("页码: " + page + ", 每页大小: " + size);
        
        CircuitBreaker circuitBreaker = circuitBreakerFactory.create(CIRCUIT_BREAKER_NAME);
        
        return circuitBreaker.run(
            () -> {
                try {
                    Pageable pageable = PageRequest.of(page, size);
                    Page<BookDTO> result = bookService.findAllBooks(pageable);
                    System.out.println("图书查询成功，返回结果数量: " + result.getContent().size());
                    return result;
                } catch (Exception e) {
                    System.out.println("图书查询失败: " + e.getMessage());
                    throw e;
                }
            },
            throwable -> {
                System.out.println("触发图书查询熔断降级: " + throwable.getMessage());
                return Page.empty();
            }
        );
    }
    
    /**
     * 使用熔断器根据关键字搜索图书
     * @param keyword 关键字
     * @param page 页码
     * @param size 每页大小
     * @return 搜索结果
     */
    public Page<BookDTO> searchBooks(String keyword, int page, int size) {
        System.out.println("使用熔断器搜索图书");
        System.out.println("关键字: " + keyword);
        System.out.println("页码: " + page + ", 每页大小: " + size);
        
        CircuitBreaker circuitBreaker = circuitBreakerFactory.create(CIRCUIT_BREAKER_NAME);
        
        return circuitBreaker.run(
            () -> {
                try {
                    Pageable pageable = PageRequest.of(page, size);
                    Page<BookDTO> result = bookService.searchBooks(keyword, pageable);
                    System.out.println("图书搜索成功，返回结果数量: " + result.getContent().size());
                    return result;
                } catch (Exception e) {
                    System.out.println("图书搜索失败: " + e.getMessage());
                    throw e;
                }
            },
            throwable -> {
                System.out.println("触发图书搜索熔断降级: " + throwable.getMessage());
                return Page.empty();
            }
        );
    }
    
    /**
     * 使用熔断器根据分类查询图书
     * @param category 分类
     * @param page 页码
     * @param size 每页大小
     * @return 查询结果
     */
    public Page<BookDTO> findBooksByCategory(String category, int page, int size) {
        System.out.println("使用熔断器按分类查询图书");
        System.out.println("分类: " + category);
        System.out.println("页码: " + page + ", 每页大小: " + size);
        
        CircuitBreaker circuitBreaker = circuitBreakerFactory.create(CIRCUIT_BREAKER_NAME);
        
        return circuitBreaker.run(
            () -> {
                try {
                    Pageable pageable = PageRequest.of(page, size);
                    Page<BookDTO> result = bookService.findBooksByCategory(category, pageable);
                    System.out.println("图书分类查询成功，返回结果数量: " + result.getContent().size());
                    return result;
                } catch (Exception e) {
                    System.out.println("图书分类查询失败: " + e.getMessage());
                    throw e;
                }
            },
            throwable -> {
                System.out.println("触发图书分类查询熔断降级: " + throwable.getMessage());
                return Page.empty();
            }
        );
    }
    
    /**
     * 创建降级图书
     * @param id 图书ID
     * @return 降级图书信息
     */
    private BookDTO createFallbackBook(Integer id) {
        BookDTO book = new BookDTO();
        book.setId(id);
        book.setTitle("暂时无法获取图书信息");
        book.setAuthor("未知");
        book.setPublisher("未知");
        book.setPublicationYear(0);
        book.setIsbn("未知");
        book.setCategory("未知");
        book.setDescription("当前无法获取图书信息，请稍后再试");
        book.setQuantity(0);
        book.setAvailableQuantity(0);
        book.setCreatedAt(LocalDateTime.now());
        book.setUpdatedAt(LocalDateTime.now());
        return book;
    }
    
    /**
     * 创建降级图书列表
     * @return 降级图书列表
     */
    private List<BookDTO> createFallbackBookList() {
        List<BookDTO> fallbackBooks = new ArrayList<>();
        
        BookDTO book1 = new BookDTO();
        book1.setId(1);
        book1.setTitle("暂时无法获取图书信息 - 推荐图书1");
        book1.setAuthor("系统推荐");
        book1.setPublisher("图书馆系统");
        book1.setPublicationYear(2023);
        book1.setIsbn("N/A");
        book1.setCategory("推荐");
        book1.setDescription("当前图书查询服务不可用，这是系统推荐的图书。请稍后再试。");
        book1.setQuantity(0);
        book1.setAvailableQuantity(0);
        book1.setCreatedAt(LocalDateTime.now());
        book1.setUpdatedAt(LocalDateTime.now());
        
        BookDTO book2 = new BookDTO();
        book2.setId(2);
        book2.setTitle("暂时无法获取图书信息 - 推荐图书2");
        book2.setAuthor("系统推荐");
        book2.setPublisher("图书馆系统");
        book2.setPublicationYear(2023);
        book2.setIsbn("N/A");
        book2.setCategory("推荐");
        book2.setDescription("当前图书查询服务不可用，这是系统推荐的图书。请稍后再试。");
        book2.setQuantity(0);
        book2.setAvailableQuantity(0);
        book2.setCreatedAt(LocalDateTime.now());
        book2.setUpdatedAt(LocalDateTime.now());
        
        fallbackBooks.add(book1);
        fallbackBooks.add(book2);
        
        return fallbackBooks;
    }
} 